import { encodeBase64 } from "./base64";
import yaml from "js-yaml";

export const newVmessSubscriberNode = (node: SubmeNode, cfip: string) => {
  const server = cfip ?? node.host;
  const n: Subscribe = {
    name: node.name,
    type: "vmess",
    server,
    port: node.port,
    cipher: "auto",
    uuid: node.password,
    alterId: 0,
    tls: true,
    servername: node.host,
    network: "ws",
    "ws-opts": {
      path: node.path,
      headers: { Host: node.host },
    },
  };
  return n;
};

export const newTrojanSubscriberNode = (node: SubmeNode, cfip: string) => {
  const server = cfip ?? node.host;
  const n: Subscribe = {
    name: node.name,
    type: "trojan",
    server,
    port: node.port,
    password: node.password,
    network: "ws",
    "ws-opts": {
      path: node.path,
      headers: {
        Host: node.host,
      },
    },
    sni: node.host,
  };
  return n;
};

export const toV2ray = (
  nodes: SubmeNode[],
  cfip: string,
  includeOrgin: boolean
) => {
  const r = nodes.map((n) => {
    if (n.type === "trojan") {
      // trojan://密码@优选:443?host=主机&path=path(url encode)&sni=主机&type=ws#名称(url encode)
      const items: Subscribe[] = [];
      if (includeOrgin) {
        const name = `${n.name}-原始`;
        items.push(newTrojanSubscriberNode({ ...n, name }, n.host));
      }
      items.push(newTrojanSubscriberNode({ ...n }, cfip));

      const urls = items.map((v) => {
        const sni = v["ws-opts"].headers.Host;
        const path = encodeURIComponent(v["ws-opts"].path);
        const name = encodeURIComponent(v.name);
        const url = `trojan://${v.password!}@${v.server}:${
          v.port
        }?host=${sni}&path=${path}&sni=${sni}&type=${v.network}#${name}`;
        return url;
      });
      return urls.join("\n");
    }
    if (n.type === "vmess") {
      // vmess:// base64({"add":"优选","aid":"0","host":"主机","id":"uuid","net":"ws","path":"","port":"443","ps":"名称","scy":"算法","sni":"主机","tls":"tls","type":"none","v":"2"})
      const items: Subscribe[] = [];
      if (includeOrgin) {
        const name = `${n.name}-原始`;
        items.push(newVmessSubscriberNode({ ...n, name }, n.host));
      }
      items.push(newVmessSubscriberNode({ ...n }, cfip));

      const urls = items.map((v) => {
        const sni = v["ws-opts"].headers.Host;
        const path = v["ws-opts"].path;
        const data = JSON.stringify({
          add: v.server,
          aid: v.alterId!,
          host: sni,
          id: v.uuid!,
          net: v.network,
          path,
          port: v.port,
          ps: v.name,
          scy: v.cipher!,
          sni,
          tls: "tls",
          type: "none",
          v: "2",
        });
        return `vmess://${encodeBase64(data)}`;
      });

      return urls.join("\n");
    }
    return ``;
  });
  return r.join("\n");
};

export const toClash = (
  nodes: SubmeNode[],
  cfip: string,
  includeOrgin: boolean
) => {
  const s: Subscribe[] = [];
  nodes.forEach((n) => {
    if (n.type === "trojan") {
      if (includeOrgin) {
        const name = `${n.name}-原始`;
        s.push(newTrojanSubscriberNode({ ...n, name }, cfip));
      }
      s.push(newTrojanSubscriberNode({ ...n }, cfip));
    }
    if (n.type === "vmess") {
      if (includeOrgin) {
        const name = `${n.name}-原始`;
        s.push(newVmessSubscriberNode({ ...n, name }, cfip));
      }
      s.push(newVmessSubscriberNode({ ...n }, cfip));
    }
  });

  const names = nodes.map((n) => n.name);

  return yaml.dump({
    proxies: s,
    "proxy-groups": [{ name: "Proxy", type: "select", proxies: names }],
    rules: ["MATCH,Proxy"],
  });
};
